package com.common.controller.base;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import com.common.exception.LogicException;
import com.common.util.ConstantDefine;



public abstract class BaseAjaxController<T> {
	protected Logger logger = null;
	
	//获取当前线程中的request对象
	private static ThreadLocal<HttpServletRequest> currentRequest = new ThreadLocal<HttpServletRequest>();
	
	public BaseAjaxController() {
		logger = Logger.getLogger(getClass().getName());
	}

	@ModelAttribute
	public void initReqAndRep(HttpServletRequest request) {
		currentRequest.set(request);
	}
	
	/**
	 * 在当前线程中获取request对象
	 * @return
	 */
	public HttpServletRequest getRequest() {
		return (HttpServletRequest) currentRequest.get();
	}
	
	/**
	 * 统一处理系统异常
	 * 
	 * @param request
	 * @param e
	 * @return
	 */
	@ExceptionHandler
	@ResponseBody
	public Map<String, Object> exceptionHandler(Exception e) {
		logger.error(e, e);
		Map<String, Object> result = new HashMap<String, Object>();
		// 没有权限
		if (e instanceof UnauthorizedException) {
			result.put(ConstantDefine.CHECK_ERR_MSG, ConstantDefine.NO_PERMISSION);
		}else if (e instanceof MaxUploadSizeExceededException) {
			result.put(ConstantDefine.CHECK_ERR_MSG, "文件应不大于 " + getFileKB(((MaxUploadSizeExceededException) e).getMaxUploadSize()));
		
		}else if (e instanceof LogicException) {
			result.put(ConstantDefine.SYS_ERROR_KEY, e.getMessage());
		
		} else {
			
			result.put(ConstantDefine.SYS_ERROR_KEY, ConstantDefine.SYS_ERR_MSG);
		}		
		return result;
	}

	/**
	 * 初始化页面
	 * @param model 向页面传递数据
	 * @return
	 */
	@RequestMapping(value = ConstantDefine.INIT_REQ)
	public abstract String init(Model model);

	/**
	 * 带参数的初始化
	 * 
	 * @param entity
	 * @param model 向页面传递数据
	 * @return
	 */
	@RequestMapping(value = ConstantDefine.PARA_INIT_REQ)
	public abstract String init(T entity,Model model);

	/**
	 * 条件查询数据
	 * 
	 * @param entity
	 * @return
	 */
	@RequestMapping(value = ConstantDefine.LIST_REQ, method = RequestMethod.POST)
	public abstract Object queryByEntity(T entity);
	
	/**
	 * 先验证再保存
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST)
	public abstract ResponseEntity<Map<String, Object>> save(@Valid T entity, BindingResult bindingResult);

	/**
	 * 初始化更新页面
	 * 
	 * @param id
	 *            主键
	 * @return 用户信息
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "{id}", method = RequestMethod.GET)
	public abstract T updateInit(@PathVariable("id") String id);


	/**
	 * 更新实体
	 * 
	 * @param entity
	 * @param bindingResult
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT)
	public abstract ResponseEntity<Map<String, Object>> update(@Valid T entity, BindingResult bindingResult);

	/**
	 * 删除
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(method = RequestMethod.DELETE)
	public abstract ResponseEntity<Map<String, Object>> delete(@RequestBody List<String> id) ;

	/**
	 * 添加session
	 * 
	 * @param key
	 * @param objValue
	 */
	public void addSession(String key, Object objValue) {
		HttpSession session = getSession();
		session.setAttribute(key, objValue);
	}

	/**
	 * 根据key获取session
	 * 
	 * @param key
	 * @return
	 */
	public Object getSession(String key) {
		HttpSession session = getSession();
		Object obj = null;
		if (!StringUtils.isEmpty(key)) {
			obj = session.getAttribute(key);
		}
		return obj;
	}

	/**
	 * 取得当前登录用户的编号
	 * 
	 * @return
	 */
	public String getLoginPersonCode() {
		return (String) this.getSession(ConstantDefine.PERSONCODE_SESSION);
	}

	
	/**
	 * 根据key删除session
	 * 
	 * @param key
	 */
	public void removeSession(String key) {
		HttpSession session = getSession();
		if (!StringUtils.isEmpty(key)) {
			session.removeAttribute(key);
		}
	}

	/**
	 * 获取session对象
	 * 
	 * @return
	 */
	private HttpSession getSession() {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
		if (request == null) {
			return null;
		}
		HttpSession session = request.getSession(false);
		if (session == null) {
			throw new RuntimeException("太久未操作，重新登录！");
		}
		return session;
	}

	private String getFileKB(long byteFile) {
		if (byteFile == 0)
			return "0KB";
		long kb = 1024;
		return "" + byteFile / kb + "KB";
	}

	@SuppressWarnings("unused")
	private String getFileMB(long byteFile) {
		if (byteFile == 0)
			return "0MB";
		long mb = 1024 * 1024;
		return "" + byteFile / mb + "MB";
	}

}
